import { type RouteRecordRaw } from 'vue-router'

import auth from '@/plugins/auth'
import router, { constantRoutes, dynamicRoutes } from '@/router'
import { getRouters } from '@/api/menu'
import Layout from '@/layout/index.vue'
import ParentView from '@/components//ParentView/index.vue'
import InnerLink from '@/layout/components/InnerLink/index.vue'

interface PermissionState {
  routes: RouteRecordRaw[]
  addRoutes: RouteRecordRaw[]
  defaultRoutes: RouteRecordRaw[]
  topbarRouters: RouteRecordRaw[]
  sidebarRouters: RouteRecordRaw[]
}

// Deep clone function to replace JSON.parse(JSON.stringify())
function deepClone<T>(obj: T): T {
  if (obj === null || typeof obj !== 'object') return obj
  if (obj instanceof Date) return new Date(obj) as any
  if (obj instanceof Array) return obj.map((item) => deepClone(item)) as any
  if (obj instanceof Object) {
    const clonedObj = {} as T
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        clonedObj[key] = deepClone(obj[key])
      }
    }
    return clonedObj
  }
  return obj
}

const permission = {
  state: {
    routes: [],
    addRoutes: [],
    defaultRoutes: [],
    topbarRouters: [],
    sidebarRouters: [],
  } as PermissionState,
  mutations: {
    SET_ROUTES: (state: PermissionState, routes: RouteRecordRaw[]) => {
      state.addRoutes = routes
      state.routes = constantRoutes.concat(routes)
    },
    SET_DEFAULT_ROUTES: (state: PermissionState, routes: RouteRecordRaw[]) => {
      state.defaultRoutes = constantRoutes.concat(routes)
    },
    SET_TOPBAR_ROUTES: (state: PermissionState, routes: RouteRecordRaw[]) => {
      state.topbarRouters = routes
    },
    SET_SIDEBAR_ROUTERS: (state: PermissionState, routes: RouteRecordRaw[]) => {
      state.sidebarRouters = routes
    },
  },
  actions: {
    // 生成路由
    GenerateRoutes({ commit }: { commit: <T>(type: string, payload?: T) => void }) {
      return new Promise<RouteRecordRaw[]>((resolve) => {
        // 向后端请求路由数据
        getRouters().then((res: any) => {
          const sdata: RouteRecordRaw[] = deepClone(res.data)
          const rdata: RouteRecordRaw[] = deepClone(res.data)
          const sidebarRoutes = filterAsyncRouter(sdata)
          const rewriteRoutes = filterAsyncRouter(rdata, false, true)
          const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
          // rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true } as RouteRecordRaw)
          // router.addRoute(asyncRoutes)
          asyncRoutes.forEach((route) => {
            router.addRoute(route)
          })
          commit('SET_ROUTES', rewriteRoutes)
          commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
          commit('SET_DEFAULT_ROUTES', sidebarRoutes)
          commit('SET_TOPBAR_ROUTES', sidebarRoutes)
          resolve(rewriteRoutes)
        })
      })
    },
  },
}

// 遍历后台传来的路由字符串，转换为组件对象
function filterAsyncRouter(
  asyncRouterMap: any[],
  lastRouter = false,
  type = false,
): RouteRecordRaw[] {
  return asyncRouterMap.filter((route) => {
    if (type && route.children) {
      route.children = filterChildren(route.children, route as any)
    }
    if (route.component) {
      // Layout ParentView 组件特殊处理
      if (route.component === 'Layout') {
        route.component = Layout
      } else if (route.component === 'ParentView') {
        route.component = ParentView
      } else if (route.component === 'InnerLink') {
        route.component = InnerLink
      } else {
        route.component = loadView(route.component as string)
      }
    }

    if (Reflect.has(route, 'hidden')) {
      if (route.meta) {
        route.meta.hidden = route.hidden
      } else {
        route.meta = { hidden: route.hidden }
      }
      delete route['hidden']
    }

    console.log(route.name)

    if (route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children, route as any, type)
    } else {
      delete route['children']
      delete route['redirect']
    }

    return true
  }) as RouteRecordRaw[]
}

function filterChildren(childrenMap: any[], lastRouter: any = false): RouteRecordRaw[] {
  let children: RouteRecordRaw[] = []
  childrenMap.forEach((el) => {
    const newEl = { ...el }
    newEl.path = lastRouter?.path ? lastRouter.path + '/' + newEl.path : newEl.path
    newEl.name = lastRouter?.name ? lastRouter.name + newEl.name : newEl.name
    if (newEl.children && newEl.children.length && newEl.component === 'ParentView') {
      children = children.concat(filterChildren(newEl.children, newEl))
    } else {
      children.push(newEl)
    }
  })
  return children
}

// 动态路由遍历，验证是否具备权限
export function filterDynamicRoutes(routes: RouteRecordRaw[]): RouteRecordRaw[] {
  const res: RouteRecordRaw[] = []
  routes.forEach((route) => {
    if (route.meta && route.meta.permissions) {
      if (auth.hasPermiOr(route.meta.permissions as string[])) {
        res.push(route)
      }
    } else if (route.meta && route.meta.roles) {
      if (auth.hasRoleOr(route.meta.roles as string[])) {
        res.push(route)
      }
    }
  })
  return res
}

const viewModules = import.meta.glob('@/views/**/*.vue')
export const loadView = (view: string) => {
  // Validate view path to prevent security issues
  if (!view || typeof view !== 'string' || !view.match(/^[\w\/\-]+$/)) {
    console.error('Invalid view path:', view)
    return () => Promise.reject(new Error('Invalid view path'))
  }
  // 尝试多种可能的路径格式
  const possiblePaths = [
    `/src/views/${view}.vue`,
    `/src/views/${view}/index.vue`,
    `@/views/${view}.vue`,
    `@/views/${view}/index.vue`,
  ]

  // 查找匹配的路径
  const matchedPath = possiblePaths.find((path) => viewModules[path]) || ''

  if (viewModules[matchedPath]) {
    return viewModules[matchedPath]
  } else {
    return () => Promise.reject(new Error(`View ${view} not found`))
  }
}

export default permission
